

#include "xprime.h"
#include "xtest.h"
#include "xutil.h"
#include <algorithm>
#include <boost/multiprecision/cpp_int.hpp>
#include <cmath>
#include <fstream>
#include <functional>
#include <iostream>
#include <random>

//import std;

//namespace mpn = boost::multiprecision;

using namespace std;

int main()
{
    mpn::cpp_int a("");

    size_t p = x_next_random_prime();
    size_t q = x_next_random_prime();

    size_t n = p * q; //10^12

    size_t ouer = (p - 1) * (q - 1); //10^12

    //与ouer互质的数 ouer-1 就这么简单！！！这是由定理证明过的
    size_t public_key = ouer - 1;

    mpn::cpp_int ouerb(ouer), public_key_b(public_key), nb(n);

    mpn::cpp_int private_key_b = mod_inverse(public_key_b, ouerb);

    cout << "n = " << nb << endl;
    cout << "public key = " << public_key_b << endl;
    cout << "private key = " << private_key_b << endl;

    auto amass = public_key_b * private_key_b;
    cout << "amass = " << amass % ouerb << endl;

    //快速模幂算法

    cout << "a coding = " << fast_mod_exp('a', public_key_b, nb) << endl;
    cout << "a decoding = " << fast_mod_exp('a', private_key_b, nb) << endl;

    mpn::cpp_int res('a');

    cout << res << endl;

    auto en = fast_mod_exp('a', public_key_b, nb);
    cout << "encoding = " << en << endl;

    auto de = fast_mod_exp(en, private_key_b, nb);
    cout << "decoding = " << de << endl;

    return 0;
}
